﻿using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading.Tasks;

namespace Core.Framework.Common
{
    public static partial class Shell
    {

        static object _lock = new object();

        static Shell()
        {
            try
            {
                if (!File.Exists("./command.sh"))
                {
                    File.Create("./command.sh").Close();
                }

                Excuter("chmod u+x ./command.sh");
            }
            catch (Exception ex)
            {
                Console.WriteLine("command.sh init error:" + ex.Message);
            }
        }

        public static string RunInCommandFile(string command)
        {
            return RunInCommandFile(command, out string _);
        }
        public static string RunInCommandFile(string command, out string error)
        {
            error = string.Empty;
            lock (_lock)
            {
                try
                {
                    File.WriteAllText("./command.sh", command);
                    command = "sh ./command.sh";
                    string[] arr = command.Split(" ");
                    string argument = " ";
                    if (arr.Length > 1)
                    {
                        for (int i = 1; i < arr.Length; i++)
                        {
                            argument += (" " + arr[i]);
                        }
                    }
                    var output = Excuter(arr[0], argument);
                    return output;
                }
                catch (Exception ex)
                {
                    error = ex.Message;
                    return string.Empty;
                }

            }
        }



        public static Task<string> ExcuterAsync(string command)
        {
            string[] arr = command.Split(" ");
            string argument = "";
            if (arr.Length > 1)
            {
                for (int i = 1; i < arr.Length; i++)
                {
                    argument += (" " + arr[i]);
                }
            }

            var output = Task.Run(() => Excuter(arr[0], argument));
            return output;
        }

        public static string Excuter(string command)
        {
            string[] arr = command.Split(" ");
            string argument = "";
            if (arr.Length > 1)
            {
                for (int i = 1; i < arr.Length; i++)
                {
                    argument += (" " + arr[i]);
                }
            }

            var output = Excuter(arr[0], argument);

            return output;
        }

        private static string Excuter(string fileName, string argument)
        {
            Process p = new Process();

            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                p.StartInfo.FileName = "cmd.exe";
            }
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                p.StartInfo.FileName = fileName;
                p.StartInfo.Arguments = argument;
            }

            p.StartInfo.UseShellExecute = false;    //是否使用操作系统shell启动
            p.StartInfo.RedirectStandardInput = true;//接受来自调用程序的输入信息
            p.StartInfo.RedirectStandardOutput = true;//由调用程序获取输出信息
            p.StartInfo.RedirectStandardError = true;//重定向标准错误输出
            p.StartInfo.CreateNoWindow = true;//不显示程序窗口
            p.Start();//启动程序

            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                //向cmd窗口发送输入信息
                p.StandardInput.WriteLine(fileName + argument + "&exit");
            }

            p.StandardInput.AutoFlush = true;

            //获取cmd窗口的输出信息
            string output = p.StandardOutput.ReadToEnd();

            Console.WriteLine("output" + output);

            p.WaitForExit();//等待程序执行完退出进程
            p.Close();

            return output;
        }
    }
}
